package gnss

import (
	"fmt"
	"math"
)

/**
  轨道和钟差改正
*/

type IgmasSsrOrbClkSat struct {
	Satid       uint8
	Iode        uint8
	DRadial     float32
	DAlongTrack float32
	DCrossTrack float32

	DotDRadial     float64
	DotDAlongTrack float64
	DotDCrossTrack float64

	C0 float64
	C1 float64
	C2 float64
}

func (this *IgmasSsrOrbClkSat) String() string {
	return fmt.Sprintf("SatId:%d, Iode:%d, DRadial:%.4f, DAlongTrack:%.4f, DCrossTrack:%.4f, DotDRadial:%.6f, DotDAlongTrack:%.6f, DotDCrossTrack:%.6f, C0:%.4f, C1:%.6f, C2:%.8f",
		this.Satid, this.Iode, this.DRadial, this.DAlongTrack, this.DCrossTrack, this.DotDRadial, this.DotDAlongTrack, this.DotDCrossTrack, this.C0, this.C1, this.C2)
}

func EncodeIgmasSsrOrbClk(head *IgmasSsrCorrectionHead, lst []*IgmasSsrOrbClkSat, outBuf []byte, startBitN int) (bitN int) {
	bitN = EncodeIgmasSsrHead(head, outBuf, startBitN, len(lst))

	for i := 0; i < len(lst); i++ {
		itm := lst[i]
		SetBitU8(outBuf, bitN, 6, itm.Satid)
		bitN += 6

		SetBitU8(outBuf, bitN, 8, itm.Iode)
		bitN += 8

		SetBitI32(outBuf, bitN, 22, int32(math.Round(float64(itm.DRadial)/1e-4)))
		bitN += 22

		SetBitI32(outBuf, bitN, 20, int32(math.Round(float64(itm.DAlongTrack)/4e-4)))
		bitN += 20

		SetBitI32(outBuf, bitN, 20, int32(math.Round(float64(itm.DCrossTrack)/4e-4)))
		bitN += 20

		SetBitI32(outBuf, bitN, 21, int32(math.Round(itm.DotDRadial/1e-6)))
		bitN += 21

		SetBitI32(outBuf, bitN, 19, int32(math.Round(itm.DotDAlongTrack/4e-6)))
		bitN += 19

		SetBitI32(outBuf, bitN, 19, int32(math.Round(itm.DotDCrossTrack/4e-6)))
		bitN += 19

		SetBitI32(outBuf, bitN, 22, int32(math.Round(itm.C0/1e-4)))
		bitN += 22

		SetBitI32(outBuf, bitN, 21, int32(math.Round(itm.C1/1e-6)))
		bitN += 21

		SetBitI32(outBuf, bitN, 27, int32(math.Round(itm.C2/2e-8)))
		bitN += 27
	}

	return
}

func DecodeIgmasSsrOrbClk(inBuf []byte, startBitN int) (head *IgmasSsrCorrectionHead, lst []*IgmasSsrOrbClkSat, bitN int) {
	bitN = startBitN
	head = &IgmasSsrCorrectionHead{}
	head.MsgId = GetBitU16(inBuf, bitN, 12)
	bitN += 12

	head.Tow = GetBitU32(inBuf, bitN, 20)
	bitN += 20

	head.UpIntv = GetBitU8(inBuf, bitN, 4)
	bitN += 4

	head.SyncFlag = GetBitU8(inBuf, bitN, 1)
	bitN += 1

	head.Refd = GetBitU8(inBuf, bitN, 1)
	bitN += 1

	head.IOD = GetBitU8(inBuf, bitN, 4)
	bitN += 4

	head.ProvID = GetBitU16(inBuf, bitN, 16)
	bitN += 16

	head.SolID = GetBitU8(inBuf, bitN, 4)
	bitN += 4

	n := GetBitU8(inBuf, bitN, 6)
	bitN += 6
	lst = make([]*IgmasSsrOrbClkSat, n)
	for i := 0; i < len(lst); i++ {
		itm := &IgmasSsrOrbClkSat{}
		lst[i] = itm
		itm.Satid = GetBitU8(inBuf, bitN, 6)
		bitN += 6

		itm.Iode = GetBitU8(inBuf, bitN, 8)
		bitN += 8

		itm.DRadial = float32(float64(GetBitI32(inBuf, bitN, 22)) * 1e-4)
		bitN += 22

		itm.DAlongTrack = float32(float64(GetBitI32(inBuf, bitN, 20)) * 4e-4)
		bitN += 20

		itm.DCrossTrack = float32(float64(GetBitI32(inBuf, bitN, 20)) * 4e-4)
		bitN += 20

		itm.DotDRadial = float64(GetBitI32(inBuf, bitN, 21)) * 1e-6
		bitN += 21

		itm.DotDAlongTrack = float64(GetBitI32(inBuf, bitN, 19)) * 4e-6
		bitN += 19

		itm.DotDCrossTrack = float64(GetBitI32(inBuf, bitN, 19)) * 4e-6
		bitN += 19

		itm.C0 = float64(GetBitI32(inBuf, bitN, 22)) * 1e-4
		bitN += 22

		itm.C1 = float64(GetBitI32(inBuf, bitN, 21)) * 1e-6
		bitN += 21

		itm.C2 = float64(GetBitI32(inBuf, bitN, 27)) * 2e-8
		bitN += 27
	}

	return
}
